// 知识点1：当我们使用引用或者指针调用一个虚成员函数时才会执行动态绑定，因为我们知道在程序运行时才知道到底调用了哪个版本的虚函数，所以所有虚函数都必须有定义

// 知识点2：引用和指针的静态类型与动态类型不同的这一事实是C++语言支持多态性的根本所在(必须是虚函数)

// 知识点3：一个派生类的函数成员如果覆盖了基类的继承而来的虚函数，则它的形参类型必须与被它覆盖的基类函数完全一致，返回类型也必须相匹配，但当类的虚函数的返回类型是类本身的指针或者引用时，返回类型可以不同

// 知识点4：派生类如果定义了一个与基类虚函数同名函数，但参数列表不相同的话，仍然是合法行为，编译器会认为该函数与基类虚函数是相互独立的，但这往往是把形参列表弄错了的错误，编译器发现不了，所以C++11有一个好东西，在其后加上override表示其要对基类的函数进行覆盖，若未覆盖，编译器报错，我们可以发现自己的错误

// 知识点5：虚函数可以有默认实参，若函数调用了默认实参，则实参值由静态类型决定，所以基类和派生类中定义的默认实参最好一致

// 知识点6：某些情况下，我们不希望进行动态绑定，我们可使用作用域运算符强行指定其执行哪个版本，进行回避虚函数—一般情况下是成员函数中的代码才需要以防止自己调用自身造成无限循环
#include "ex15_11.h"
#include <algorithm>
#include <iostream>
#include <vector>

int main(int argc, char **argv) {
  Quote b1("龙族I", 128);
  // bulk_quote b2(string("龙族II"), 128.0, 10, 0.7);
  // number_quote b3(string("龙族III"), 128.0, 10, 0.7);
  print_total(cout, b1, 10);
  // print_total(cout, b2, 10);
  cout << endl;
  b1.debug();
  // b2.debug();
  // b3.debug();
  system("pause");
  return 0;
}